#include <stdio.h>
#include <string.h>
#include <opencv2/opencv.hpp> // 可以考虑换成别的库, ... 争取简化一些. 

void encodeToImg(char* imgname, char* filename);
void decodeToFile(char* filename, char* imgname);

void encodeToImg(char* imgname, char* filename)
{
    FILE* f = fopen(filename, "rb");
    fseek(f, 0, SEEK_END);
    long filesize = ftell(f);
    fseek(f, 0, SEEK_SET); // 通过ftell确定文件大小, 别忘了文件指针移回来

    cv::Mat img(256, 256, CV_8UC3, cv::Scalar_<unsigned char>(0,0,0)); // 随便指定了一个大小的图像. 这里将来可以改进. 
    
    memcpy(img.data, (long*)&filesize, sizeof(filesize)); // 非得使用memcpy吗?
    fread(img.data + sizeof(filesize), sizeof(unsigned char), filesize, f);

    cv::imwrite(imgname, img);    

    fclose(f);
    return;
}

void decodeToFile(char* filename, char* imgname)
{
    FILE* f = fopen(filename, "wb");
    cv::Mat img = cv::imread(imgname);
    long filesize = 0;

    memcpy(&filesize, img.data, sizeof(filesize));
    fwrite(img.data+sizeof(filesize), sizeof(unsigned char), filesize, f);
    
    fclose(f);
    return;
}

int main(int argc, char** argv, const char** env)
{
    if (argc == 3)
    {
        decodeToFile(argv[1], argv[2]);
    }
    else if ((argc == 4) && (strcmp(argv[1], "encode") == 0))
    {
        encodeToImg(argv[2], argv[3]);
    }
    else if ((argc == 4) && (strcmp(argv[1], "decode") == 0))
    {
        decodeToFile(argv[2], argv[3]);
    }
    else
    {
        printf("Number of arguments are wrong...\n");
    } 
    return 0;
}

// 某个简单的编译方法... 
// g++ main.cpp -o main -I/usr/include/opencv4 -lopencv_core -lopencv_imgcodecs